メッセージ・フローグラフの例
この例では、すべての x = 1 to 10
の合計 x*x + x*x*x
を計算します。この例のレイアウトは、下図のようになります。
それぞれの値は、broadcast_node<int>
input
を介して入力されます。このノードは、値を squarer
と cuber
(x*x
および x*x*x
を計算) にブロードキャストします。これらのノードの出力は、join
のポートの 1 つに送られます。join_node<std::tuple<int,int>> join
で両方の値を含むタプルが作成され、summer
(両方の値を合計に追加) に送られます。squarer
と cuber
はどちらも無制限に並列化できます。つまり、複数の値を同時に処理できます。最後の summer
(共有の合計を更新) は、共有値をロックしなくてもいいように、一度に 1 つの受け取ったタプルのみ処理します。
#include <cstdio>
#include
"oneapi/tbb/flow_graph.h"
using namespace oneapi::tbb::flow;
struct square {
int operator()(int v) { return v*v; }
};
struct cube {
int operator()(int v) { return v*v*v; }
};
class sum {
int &my_sum;
public:
sum( int &s ) : my_sum(s) {}
int operator()( std::tuple<int, int> v ) {
my_sum += get<0>(v) + get<1>(v);
return my_sum;
}
};
int main() {
int result = 0;
graph g;
broadcast_node<int> input(g);
function_node<int,int> squarer( g, unlimited, square() );
function_node<int,int> cuber( g, unlimited, cube() );
join_node<std::tuple<int,int>, queueing> join( g );
function_node<std::tuple<int,int>,int>
summer( g, serial, sum(result) );
make_edge( input, squarer );
make_edge( input, cuber ); make_edge( squarer, get<0>( join.input_ports() ) );
make_edge( cuber, get<1>( join.input_ports() ) );
make_edge( join, summer );
for (int i = 1; i <= 10; ++i)
input.try_put(i);
g.wait_for_all();
printf("Final result is %d\n", result);
return 0;
}
上記のサンプルコードでは、square
、cube
、sum
クラスは 3 つのユーザー定義操作を定義しています。各クラスは function_node
の作成に使用されます。
main
関数で、フローグラフがセットアップされ、値 1-10 が input
ノードに送られます。この例のノードはすべて int
タイプの値を渡します。この例で使用されているノードはすべてテンプレート・クラスであるため、ポインターとオブジェクトを含む、コピー構築をサポートするすべてのタイプで使用できます。